package xiang.weiyu.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import xiang.weiyu.common.BaseContext;
import xiang.weiyu.common.R;
import xiang.weiyu.dto.OrdersDto;
import xiang.weiyu.pojo.*;
import xiang.weiyu.service.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("order")
@Slf4j
public class OrdersController {
    //文件生成路径
    @Value("${reggie.path}")
    private String path;
    @Autowired
    private OrdersService ordersService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private AddressBookService addressBookService;

    /**
     * 订单提交
     *
     * @param orders
     * @return R<String>
     */
    @PostMapping("/submit")
    public R<String> orderSubmit(@RequestBody Orders orders) {
        ordersService.submit(orders);
        return R.success("订单提交成功");
    }

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @return R<Page < OrdersDto>>
     */
    @GetMapping("/userPage")
    public R<Page<OrdersDto>> getPage(int page, int pageSize, HttpServletRequest request) {
        Long userId = BaseContext.getCurrentId();
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(Orders::getUserId, userId);
        qw.orderByDesc(Orders::getOrderTime);
        ordersService.page(pageInfo, qw);

        Page<OrdersDto> ordersDtoPage = new Page<>();
        //1.拷贝分页信息到Page<OrdersDto>中
        BeanUtils.copyProperties(pageInfo, ordersDtoPage, "records");
        //2.给Page<OrdersDto>的records属性赋值
        List<Orders> records = pageInfo.getRecords();
        List<OrdersDto> ordersDtos = records.stream().map((record) -> {
            OrdersDto dto = new OrdersDto();

            //1.拷贝Orders到OrdersDto中
            BeanUtils.copyProperties(record, dto);

            //2.查找List<OrderDetails>到OrdersDto中
            LambdaQueryWrapper<OrderDetail> qw2 = new LambdaQueryWrapper<>();
            qw2.eq(record.getId() != null, OrderDetail::getOrderId, record.getId());
            List<OrderDetail> list = orderDetailService.list(qw2);
            dto.setOrderDetails(list);

            //3.拷贝addressBook里的信息到OrdersDto中
            LambdaQueryWrapper<AddressBook> qw3 = new LambdaQueryWrapper<>();
            qw3.eq(record.getUserId() != null, AddressBook::getUserId, record.getUserId());
            qw3.eq(AddressBook::getIsDefault, 1);
            AddressBook one = addressBookService.getOne(qw3);
            BeanUtils.copyProperties(one, dto, "id");
            return dto;
        }).collect(Collectors.toList());
        ordersDtoPage.setRecords(ordersDtos);
        return R.success(ordersDtoPage);
    }

    /**
     * (数据回显)订单
     *
     * @param page
     * @param pageSize
     * @return R<Page < Orders>>
     */
    @GetMapping("/page")
    public R<Page<Orders>> getPage2(int page, int pageSize, String number, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    LocalDateTime beginTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.like(number != null, Orders::getNumber, number);
        qw.between(beginTime != null && endTime != null, Orders::getOrderTime, beginTime, endTime);
        qw.orderByDesc(Orders::getOrderTime);
        ordersService.page(pageInfo, qw);
        return R.success(pageInfo);
    }

    /**
     * 状态修改
     *
     * @param orders
     * @return R<String>
     */
    @PutMapping
    public R<String> updateStatus(@RequestBody Orders orders) {
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(orders.getId() != null, Orders::getId, orders.getId());
        Orders one = ordersService.getOne(qw);
        one.setStatus(orders.getStatus());//1待付款，2待派送，3已派送，4已完成，5已取消
        ordersService.updateById(one);
        return R.success("订单状态修改成功");
    }

    /**
     * 前端传入数据有误，此接口无法运行，应该为order_id,结果接收到address_book_id
     *
     * @param orders
     * @return R<String>
     */
    @PostMapping("again")
    public R<String> againOrder(@RequestBody Orders orders) {//id: orders id
        ordersService.againOrder(orders);
        return R.success("再来一单成功");
    }

    /**
     * 订单明细表导出/下载功能
     *
     * @param response
     * @throws Exception
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {

        //写入excel 【(✔)apache poi | 阿里的easy excel】
        //2.1创建一个工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();

        //2.1创建一个工作表
        XSSFSheet sheet = workbook.createSheet("订单明细表");

        //createRow: 行
        //创建一行，0代表第一行
        XSSFRow row01 = sheet.createRow(0);

        //createCell: 列
        //创建一个单元格
        XSSFCell cell01 = row01.createCell(0);
        cell01.setCellValue("订单号");
        XSSFCell cell02 = row01.createCell(1);
        cell02.setCellValue("订单状态");
        XSSFCell cell03 = row01.createCell(2);
        cell03.setCellValue("用户");
        XSSFCell cell04 = row01.createCell(3);
        cell04.setCellValue("手机号");
        XSSFCell cell05 = row01.createCell(4);
        cell05.setCellValue("地址");
        XSSFCell cell06 = row01.createCell(5);
        cell06.setCellValue("下单时间");
        XSSFCell cell07 = row01.createCell(6);
        cell07.setCellValue("实收金额(元)");

        //查询所有的订单数据 List<>
        List<Orders> list = ordersService.list();
        for (int i = 0; i < list.size(); i++) {
            Orders orders = list.get(i);
            XSSFRow row = sheet.createRow(1 + i);//从第二行开始
            XSSFCell cell1 = row.createCell(0);
            cell1.setCellValue(orders.getNumber());
            XSSFCell cell2 = row.createCell(1);
            Integer status = orders.getStatus();
            String status2 = "";
            switch (status) {//1待付款，2待派送，3已派送，4已完成，5已取消
                case 1:
                    status2 = "待付款";
                    break;
                case 2:
                    status2 = "待派送";
                    break;
                case 3:
                    status2 = "已派送";
                    break;
                case 4:
                    status2 = "已完成";
                    break;
                case 5:
                    status2 = "已取消";
                    break;
            }
            cell2.setCellValue(status2);
            XSSFCell cell3 = row.createCell(2);
            cell3.setCellValue(orders.getUserName());
            XSSFCell cell4 = row.createCell(3);
            cell4.setCellValue(orders.getPhone());
            XSSFCell cell5 = row.createCell(4);
            cell5.setCellValue(orders.getAddress());
            XSSFCell cell6 = row.createCell(5);
            cell6.setCellValue(orders.getOrderTime().toString());
            XSSFCell cell7 = row.createCell(6);
            cell7.setCellValue(orders.getAmount().toString());

        }
        //response写入浏览器
        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String("订单明细表".getBytes("utf-8"), "ISO8859-1") + ".xlsx");//
        OutputStream out = response.getOutputStream();
        workbook.write(out);
        out.flush();
        response.flushBuffer();
    }
}
